﻿using Ebusiness_UserService.DomainEvent.User;
using Ebusiness_UserService.DomainService.Dto;
using Ebusiness_UserService.Model;
using Ebusiness_UserService.Repositorys;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;

namespace Ebusiness_UserService.DomainService
{
    /// <summary>
    /// 领域服务:聚合内的业务逻辑。
    /// </summary>
    [Dependency(ServiceLifetime.Transient)]
    public class UserMannager
    {
        public IUserRepository UserRepository { get; set; }

        public ISmsCodeSender SmsCodeSender { get; set; }

        /// <summary>
        /// 用户账户和密码登录
        /// </summary>
        /// <param name="phoneNum"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task<UserAccessResult> CheckLoginAsync(PhoneNumber phoneNum, string password)
        {
            User? user = await UserRepository.FindOneAsync(phoneNum);
            UserAccessResult result;
            if (user == null)//找不到用户
                result = UserAccessResult.PhoneNumberNotFound;
            else if (IsLockOut(user))//用户被锁定
                result = UserAccessResult.Lockout;
            //else if (user.userAccessFail.lsLockOut())//用户被锁定
            //    result = UserAccessResult.Lockout;
            else if (user.HasPassword() == false)//没设密码
                result = UserAccessResult.NoPassword;
            else if (user.checkPassword(password))
                result = UserAccessResult.OK;
            else
                result = UserAccessResult.PasswordError;
            if (user != null)
            {
                if (result == UserAccessResult.OK)
                {
                    ResetAccessFail(user);
                }
                else
                {
                    AccessFail(user);
                }
            }
            //发布事件  等待 确保一个工作单元要么全部成功 要么全部失败
            await UserRepository.PublishEventAsync(new UserAccessResultEvent() { PhoneNumber = phoneNum, Result = result });
            return result;
        }

        /// <summary>
        /// 用户验证码登录
        /// </summary>
        /// <param name="phoneNum"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public async Task<CheckCodeResult> CheckCodeAsync(PhoneNumber phoneNum, string code)
        {
            User? user = await UserRepository.FindOneAsync(phoneNum);
            if (user == null)
                return CheckCodeResult.PhoneNumberNotFound;
            else if (IsLockOut(user))
                return CheckCodeResult.Lockout;
            string? codeInServer = await UserRepository.FindPhoneNumberCodeAsync(phoneNum);
            if (codeInServer == null)
            {
                AccessFail(user);
                return CheckCodeResult.CodeError;
            }
            else if (codeInServer == code)
                return CheckCodeResult.OK;
            else
            {
                AccessFail(user);
                return CheckCodeResult.CodeError;
            }

        }

        public void ResetAccessFail(User user)
        {
            user.userAccessFail.Reset();
        }

        public bool IsLockOut(User user)
        {
            return user.userAccessFail.lsLockOut();
        }

        public void AccessFail(User user)
        {
            user.userAccessFail.Fail();
        }
    }
}
